#ifndef _RTP_SEND_PS_H_
#define _RTP_SEND_PS_H_

#include "video.h"
#include "video_mpp.h" // VIDEO_MAX_SIZE
#include "audio.h"     // AUDIO_SIZE

// #define UDP_EN

/***
 *@remark:  讲传入的数据按位一个一个的压入数据
 *@param :  buffer   [in]  压入数据的buffer
 *          count    [in]  需要压入数据占的位数
 *          bits     [in]  压入的数值
 */
#define bits_write(buffer, count, bits)                                          \
    {                                                                            \
        bits_buffer_s *p_buffer = (buffer);                                      \
        int i_count = (count);                                                   \
        uint64_t i_bits = (bits);                                                \
        while (i_count > 0)                                                      \
        {                                                                        \
            i_count--;                                                           \
            if ((i_bits >> i_count) & 0x01)                                      \
            {                                                                    \
                p_buffer->p_data[p_buffer->i_data] |= p_buffer->i_mask;          \
            }                                                                    \
            else                                                                 \
            {                                                                    \
                p_buffer->p_data[p_buffer->i_data] &= ~p_buffer->i_mask;         \
            }                                                                    \
            p_buffer->i_mask >>= 1;    /*操作完一个字节第一位后，操作第二位*/    \
            if (p_buffer->i_mask == 0) /*循环完一个字节的8位后，重新开始下一位*/ \
            {                                                                    \
                p_buffer->i_data++;                                              \
                p_buffer->i_mask = 0x80;                                         \
            }                                                                    \
        }                                                                        \
    }

#define PS_HDR_LEN 14  // ps header        字节长度
#define SYS_HDR_LEN 18 // ps system header 字节长度
#define PSM_HDR_LEN 24 // ps system map    字节长度
#define PES_HDR_LEN 19 // ps pes header    字节长度
#define RTP_HDR_LEN 12 // rtp header       字节长度
#define RTP_VERSION 2  // rtp 版本号

#define RTP_MAX_PACKET_BUFF 1460  // rtp传输时的最大包长
#define PS_PES_PAYLOAD_SIZE 65522 // 分片进循发送的最大长度上限

union LESize
{
    unsigned short int length;
    unsigned char byte[2];
};

struct bits_buffer_s
{
    unsigned char *p_data;
    unsigned char i_mask;
    int i_size;
    int i_data;
};

struct Data_Info_s
{
    uint64_t s64CurPts;
    int IFrame;
    uint16_t u16CSeq;
    uint32_t u32Ssrc;
    char szBuff[RTP_MAX_PACKET_BUFF + 2];  // 这个地方需要加上2是因为在tcp的时候, 由于每一包的最前面需要加上2个字节的长度信息, 继续使用这个长度会导致越界
};

class cls_rtp_send_ps
{
public:
    cls_rtp_send_ps(cls_sip_client *p_sip_client);
    ~cls_rtp_send_ps();

    cls_sip_client *sip_client;

    mqd_t video_queue;
    mqd_t audio_queue;

    bool sendps_running;

    std::unique_ptr<std::thread> main_loop_thread;

    void sendps_main_loop();
    void sendps_loop_start();
    void sendps_loop_stop();

private:
    Data_Info_s pPacker;

    int socket_fd;
    int local_port;
    int server_port;
    string server_ip;

    u8 use_tcp; // 暂时先这样吧, 我还没想好怎么设置

    char vid_buf[VIDEO_MAX_SIZE + PES_HDR_LEN + 2];
    char aud_buf[AUDIO_SIZE + PES_HDR_LEN];

    void init_packer();
    void init_tcp();
    void init_udp();

    int gb28181_streampackageForH264(char *pData, int nFrameLen, Data_Info_s *pPacker, int stream_type);
    int gb28181_make_ps_header(char *pData, unsigned long long s64Scr);
    int gb28181_make_sys_header(char *pData);
    int gb28181_make_psm_header(char *pData);
    int gb28181_make_pes_header(char *pData, int stream_id, int payload_len, unsigned long long pts, unsigned long long dts);
    int gb28181_send_rtp_pack(char *databuff, int nDataLen, int mark_flag, Data_Info_s *pPacker);
    int gb28181_make_rtp_header(char *pData, int marker_flag, unsigned short cseq, long long curpts, unsigned int ssrc);
    int SendDataBuff(char *buff, int size);
};

#endif //  _RTP_SEND_PS_H_